package com.banban.user.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.banban.user.domain.ConversationLog;
import com.banban.user.domain.PromptTemplate;
import com.banban.user.domain.SessionInfo;
import com.banban.user.domain.SysUser;
import com.banban.user.dto.ConversationLogAddDTO;
import com.banban.user.dto.ConversationLogSuggestDTO;
import com.banban.user.dto.ConversationSelectDTO;
import com.banban.user.dto.SessionInfoSelectDTO;
import com.banban.user.exception.BusinessException;
import com.banban.user.mapper.ConversationLogMapper;
import com.banban.user.mapper.SessionInfoMapper;
import com.banban.user.mapper.SysUserMapper;
import com.banban.user.service.ConversationLogService;
import com.banban.user.service.PromptTemplateService;
import com.banban.user.service.PromptTemplateVersionService;
import com.banban.user.util.RedisUtil;
import com.banban.user.util.UniqueIDUtil;
import com.banban.user.vo.ConversationLogAddVO;
import com.banban.user.vo.ConversationSelectVO;
import com.banban.user.vo.SessionInfoVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;

/**
 * @author 张振飞
 * @Package com.banban.user.service.impl
 * @date 2025/4/19 11:14
 */
@Service
public class ConversationLogServiceImpl extends ServiceImpl<ConversationLogMapper, ConversationLog> implements ConversationLogService {

    @Resource
    private ConversationLogMapper mapper;

    @Autowired
    private PromptTemplateVersionService promptTemplateVersionService;

    @Resource
    private PromptTemplateService promptTemplateService;

    @Resource
    private SessionInfoMapper sessionInfoMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private SysUserMapper userMapper;

    private static final String BANBAN_SYSTEM_MESSAGE = "BANBAN_SYSTEM_MESSAGE";
    private static final String BANBAN_USER_MESSAGE = "BANBAN_USER_MESSAGE_";

    @Override
    public ConversationLogAddVO add(ConversationLogAddDTO dto) {
        QueryWrapper<ConversationLog> qw =new QueryWrapper<>();
        qw.eq("request_id",dto.getRequestId());
        List<ConversationLog> list = super.list(qw);
        if (list != null && !list.isEmpty()){
            throw new BusinessException("requestId重复");
        }
        ConversationLog conversationLog = new ConversationLog();
        BeanUtils.copyProperties(dto,conversationLog);
        conversationLog.setId(String.valueOf(UniqueIDUtil.generateId()));
        conversationLog.setCreateBy(StpUtil.getLoginIdAsString());

        //promptTemplateId
        String promptTemplateId;
        if (StringUtils.isNotBlank(dto.getPromptTemplateId())){
            promptTemplateId = dto.getPromptTemplateId();
        }else {
            promptTemplateId = promptTemplateVersionService.getPromptTemplateId();
        }
        conversationLog.setPromptTemplateId(promptTemplateId);
        //提示词内容
        PromptTemplate promptTemplate = promptTemplateService.getById(promptTemplateId);
        String prompt = promptTemplate.getPrompt();

        //获取系统提示词
        Object o = redisUtil.get(BANBAN_SYSTEM_MESSAGE);
        if (o != null){
            Map<String, String> extSystem = (Map<String, String>) o;
            prompt = this.replaceVariable(prompt, extSystem);
        }

        //获取个人提示词
        Object o1 = redisUtil.get(BANBAN_USER_MESSAGE+ StpUtil.getLoginIdAsString());
        if (o1 != null){
            Map<String, String> extUser = (Map<String, String>) o1;
            prompt = this.replaceVariable(prompt, extUser);
        }
        conversationLog.setSystemMessage(prompt);
        super.save(conversationLog);
        ConversationLogAddVO vo = new ConversationLogAddVO();
        BeanUtils.copyProperties(conversationLog,vo);

        QueryWrapper<SessionInfo> sessionInfoQueryWrapper = new QueryWrapper<>();
        sessionInfoQueryWrapper.eq("session_id",dto.getSessionId());
        List<SessionInfo> sessionInfos = sessionInfoMapper.selectList(sessionInfoQueryWrapper);
        if (sessionInfos == null || sessionInfos.isEmpty()){
            SessionInfo sessionInfo = new SessionInfo();
            sessionInfo.setSessionId(dto.getSessionId());
            sessionInfo.setUserId(StpUtil.getLoginIdAsString());
            sessionInfoMapper.insert(sessionInfo);
        }
        return vo;
    }

    @Override
    public void suggest(ConversationLogSuggestDTO dto) {
        ConversationLog conversationLog = new ConversationLog();
        conversationLog.setRequestId(dto.getRequestId());
        conversationLog.setUpType(dto.getType());
        conversationLog.setSessionId(dto.getSessionId());
        conversationLog.setUpdateBy(StpUtil.getLoginIdAsString());
        mapper.suggest(conversationLog);
    }

    @Override
    public List<ConversationSelectVO> select(ConversationSelectDTO dto) {

        if (StringUtils.isNotBlank(dto.getRequestId())){
            //查询该对话记录
            String requestId = dto.getRequestId();
            QueryWrapper<ConversationLog> qw = new QueryWrapper<>();
            qw.eq("request_id",requestId);
            ConversationLog one = mapper.selectOne(qw);
            if (one!=null){
                String sessionId = one.getSessionId();
                QueryWrapper<ConversationLog> qw2 = new QueryWrapper<>();
                qw2.eq("session_id",sessionId);
                qw2.orderByAsc("create_time");
                List<ConversationLog> conversationLogs = mapper.selectList(qw2);
                List<ConversationSelectVO> vos = new ArrayList<>();
                for (ConversationLog conversationLog : conversationLogs) {
                    ConversationSelectVO vo = new ConversationSelectVO();
                    BeanUtils.copyProperties(conversationLog,vo);
                    vos.add(vo);
                }
                return vos;
            }else {
                return Collections.emptyList();
            }
        }

        String userId = dto.getUserId();

        String dateTime = dto.getDateTime();
        QueryWrapper<ConversationLog> qw = new QueryWrapper<>();
        qw.eq("create_by",userId);
        if (StringUtils.isNotEmpty(dateTime)){
            LocalDate date = LocalDate.parse(dateTime);
            Date startOfDay = Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant());
            Date endOfDay = Date.from(date.atTime(23, 59, 59).atZone(ZoneId.systemDefault()).toInstant());
            qw.gt("create_time",startOfDay);
            qw.le("create_time", endOfDay);   // 小于等于当天结束时间
        }
        qw.orderByAsc("create_time");
        List<ConversationLog> conversationLogs = mapper.selectList(qw);
        if (!conversationLogs.isEmpty()){
            List<ConversationSelectVO> vos = new ArrayList<>();
            for (ConversationLog conversationLog : conversationLogs) {
                ConversationSelectVO vo = new ConversationSelectVO();
                BeanUtils.copyProperties(conversationLog,vo);
                vos.add(vo);
            }
            return vos;
        }
        return Collections.emptyList();
    }

    @Override
    public IPage<SessionInfoVO> selectSessionInfoPage(SessionInfoSelectDTO dto) {
        String phone = dto.getPhone();
        String realName = dto.getRealName();
        String nickName = dto.getNickName();
        if (phone != null || realName != null || nickName != null){
            List<SysUser> users =  userMapper.selectUser(dto);
            if (users != null && !users.isEmpty()){
                List<String> userIds = new ArrayList<>();
                for (SysUser user : users) {
                    userIds.add(user.getId());
                }

            }else {
                return new Page<>(dto.getPage(),dto.getLimit());
            }
        }

        return null;
    }

    /**
     * 变量代入
     * @param promptTemplate
     * @param ext
     * @return
     */
    private String replaceVariable(String promptTemplate, Map<String, String> ext) {
        if (ext != null) {
            for (String s : ext.keySet()) {
                promptTemplate = promptTemplate.replace("{{" + s + "}}", ext.get(s));
            }
        }
        return promptTemplate;
    }
}
